<template>
	<view class="tui-skeleton-cmomon tui-skeleton-box" :style="{width: winWidth+'px', height:winHeight+'px', backgroundColor:backgroundColor}">
		<view class="tui-skeleton-cmomon" v-for="(item,index) in skeletonElements" :key="index" :style="{width: item.width+'px', height:item.height+'px', left: item.left+'px', top: item.top+'px',backgroundColor: skeletonBgColor,borderRadius:getRadius(item.skeletonType,borderRadius)}"></view>
		<view class="tui-loading" :class="[getLoadingType(loadingType)]" v-if="isLoading"></view>
	</view>
</template>

<script>
	export default {
		name: "tuiSkeleton",
		props: {
			//选择器(外层容器)
			selector: {
				type: String,
				default: "tui-skeleton"
			},
			//外层容器背景颜色
			backgroundColor: {
				type: String,
				default: "#fff"
			},
			//骨架元素背景颜色
			skeletonBgColor: {
				type: String,
				default: "#e9e9e9"
			},
			//骨架元素类型：矩形，圆形，带圆角矩形["rect","circular","fillet"]
			//默认所有，根据页面情况进行传值
			//页面对应元素class为：tui-skeleton-rect，tui-skeleton-circular，tui-skeleton-fillet
			//如果传入的值不在下列数组中，则为自定义class值，默认按矩形渲染
			skeletonType: {
				type: Array,
				default () {
					return ["rect", "circular", "fillet"]
				}
			},
			//圆角值，skeletonType=fillet时生效
			borderRadius: {
				type: String,
				default: "16rpx"
			},
			//骨架屏预生成数据：提前生成好的数据，当传入该属性值时，则不会再次查找子节点信息
			preloadData: {
				type: Array,
				default () {
					return []
				}
			},
			//是否需要loading
			isLoading: {
				type: Boolean,
				default: true
			},
			//loading类型[1-10]
			loadingType: {
				type: Number,
				default: 1
			}
		},
		created() {
			const res = uni.getSystemInfoSync();
			this.winWidth = res.windowWidth;
			this.winHeight = res.windowHeight;
			//如果有预生成数据，则直接使用
			this.isPreload(true)
		},
		mounted() {
			this.$nextTick(() => {
				this.nodesRef(`.${this.selector}`).then((res) => {
					if(res && res[0]){
						this.winHeight = res[0].height + Math.abs(res[0].top)
					}
				});
				!this.isPreload() && this.selectorQuery()
			})

		},
		data() {
			return {
				winWidth: 375,
				winHeight: 800,
				skeletonElements: []
			};
		},
		methods: {
			getLoadingType: function(type) {
				let value = 1
				if (type && type > 0 && type < 11) {
					value = type
				}
				return 'tui-loading-' + value
			},
			getRadius: function(type, val) {
				let radius = "0"
				if (type == "circular") {
					radius = "50%"
				} else if (type == "fillet") {
					radius = val
				}
				return radius;
			},
			isPreload(init) {
				let preloadData = this.preloadData || []
				if (preloadData.length) {
					init && (this.skeletonElements = preloadData)
					return true
				}
				return false
			},
			async selectorQuery() {
				let skeletonType = this.skeletonType || []
				let nodes = []
				for (let item of skeletonType) {
					let className = '';
					// #ifndef MP-WEIXIN
					className = `.${item}`;
					if (~'rect_circular_fillet'.indexOf(item)) {
						className = `.${this.selector}-${item}`;
					}
					// #endif
					
					// #ifdef MP-WEIXIN
					className = `.${this.selector} >>> .${item}`;
					if (~'rect_circular_fillet'.indexOf(item)) {
						className = `.${this.selector} >>> .${this.selector}-${item}`;
					}
					// #endif
					await this.nodesRef(className).then((res) => {
						res.map(d => {
							d.skeletonType = item
						})
						nodes = nodes.concat(res)
					})
				}
				this.skeletonElements = nodes
			},
			async nodesRef(className) {
				return await new Promise((resolve, reject) => {
					uni.createSelectorQuery().selectAll(className).boundingClientRect((res) => {
						if (res) {
							resolve(res);
						} else {
							reject(res)
						}
					}).exec();
				})
			}
		}
	}
</script>

<style scoped>
	.tui-skeleton-cmomon {
		position: absolute;
		z-index: 99999;
	}

	.tui-skeleton-box {
		left: 0;
		top: 0;
	}

	.tui-loading {
		display: inline-block;
		vertical-align: middle;
		width: 40rpx;
		height: 40rpx;
		background: 0 0;
		border-radius: 50%;
		border: 2px solid;
		animation: tui-rotate 0.7s linear infinite;
		position: fixed;
		z-index: 999999;
		left: 50%;
		top: 50%;
		margin-left: -20rpx;
		margin-top: -20rpx;
	}

	.tui-loading-1 {
		border-color: #e5e5e5 #e5e5e5 #e5e5e5 #5677fc;
	}

	.tui-loading-2 {
		border-color: #e5e5e5 #e5e5e5 #e5e5e5 #8f8d8e;
	}

	.tui-loading-3 {
		border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) #fff;
	}

	.tui-loading-4 {
		border-color: #e5e5e5 #e5e5e5 #e5e5e5 #35b06a;
	}

	.tui-loading-5 {
		border-color: #e5e5e5 #e5e5e5 #e5e5e5 #fc872d;
	}

	.tui-loading-6 {
		border-color: #e5e5e5 #e5e5e5 #e5e5e5 #eb0909;
	}

	.tui-loading-7 {
		border-color: #5677fc transparent #5677fc transparent;
	}

	.tui-loading-8 {
		border-color: #35b06a transparent #35b06a transparent;
	}

	.tui-loading-9 {
		border-color: #fc872d transparent #fc872d transparent;
	}

	.tui-loading-10 {
		border-color: #eb0909 transparent #eb0909 transparent;
	}

	@-webkit-keyframes tui-rotate {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes tui-rotate {
		0% {
			transform: rotate(0);
		}

		100% {
			transform: rotate(360deg);
		}
	}
</style>
